package main
import (
	"fmt"
	"time"
	"sync"
)

//计算1-15的各个数的阶乘，并放到map中
//使用goroutine完成
var (
	myMap = make(map[int]int,10)

	//1）声明一个全局的互斥锁  lock 是一个全局的互斥锁   sync 是包： synchornized 同步
	//Mutex 互斥
	lock sync.Mutex

)

func test(n int){
	res := 1
	for i:=1;i<=n;i++{
		res *=i
	}
	lock.Lock()  //2）加锁  防止并行写入map
	myMap[n] = res
	lock.Unlock()  //3）解锁
}


func main(){
	//开启15个协程完成任务 
	for i:=1;i<=15;i++{
		go test(i)
	} 
	//为防止主线程跑完，协程还没走完，休眠 10秒？？？
	time.Sleep(time.Second * 10)
	//本来10秒是可以跑完协程，但是主线程不知道可以，所有主线程可能会产生资源竞争，故在下面遍历的时候还是要加入互斥锁
	lock.Lock()
	for i,v := range myMap{
		fmt.Printf("map[%d]:%d\n",i,v)
	}
	lock.Unlock()


	//没有加锁的情况下以上操作回报如下的错，问题引出
	//fatal error: concurrent map writes  不能同时对map并行写入  会产生竞争资源的问题
	//并且具体要休眠多久？？？



	//引出channel的需求
	//1、全局变量加互斥锁解决资源竞争
	//2、channel
	//正确操作：
	//1）声明一个全局的互斥锁
	//2）加锁
	//3）解锁

	//结果：
	//加锁后不会产生资源竞争，但是map里面的结果数据不对！原因就是数据溢出
	//在不溢出的情况下，竞争资源的问题解决了，但是有个问题？就是具体要休眠多少秒？
}

